﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace ProjectClone.Tool
{
    public class XMLHelper
    {
        public static void ModifyProjectCsproj(string path, string _sName, string _dName, string sourcePath, string sourceSLNPath)
        {
            var projectPathDir = Path.GetDirectoryName(path);

            string sourcePathDir = Path.GetDirectoryName(sourcePath);

            string sourceSLNPathDir = Path.GetDirectoryName(sourceSLNPath);

            var doc = new XmlDocument();
            doc.Load(path);

            XmlNode rootNode = null;

            foreach (XmlNode item in doc.ChildNodes)
            {
                if (item.Name.ToLower() == "project")
                {
                    rootNode = item;
                }
            }

            if (rootNode == null) return;

            var ItemGroup = GetChildrenNodes(rootNode, "ItemGroup");

            foreach (var node in ItemGroup)
            {
                #region 替换ProjectReference
                var pRefItemNodes = GetChildrenNodes(node, "ProjectReference");

                foreach (var itemNode in pRefItemNodes)
                {
                    var include = GetNodeAttribute(itemNode, "Include");


                    var absPath = FileHelper.MakeAbsolutePath(sourcePathDir, include.Value);

                    var relPath = FileHelper.MakeRelativePath(sourceSLNPathDir, absPath);

                    if (relPath.StartsWith("..\\") && !File.Exists(FileHelper.MakeAbsolutePath(projectPathDir, include.Value)))
                    {
                        include.Value = FileHelper.MakeRelativePath(projectPathDir, absPath);
                    }

                    if (!include.Value.Contains(_dName)) {
                        include.Value = include.Value.Replace(_sName, _dName);
                    }

                    var nameItemNodes = GetChildrenNodes(itemNode, "Name");

                    foreach (var nameItemNode in nameItemNodes)
                    {
                        nameItemNode.InnerText = nameItemNode.InnerText.Replace(_sName, _dName);
                    }
                }
                #endregion
                #region 替换Reference
                var refItemNodes = GetChildrenNodes(node, "Reference");

                foreach (var itemNode in refItemNodes)
                {
                    var include = GetNodeAttribute(itemNode, "Include");

                    include.Value = include.Value.Replace(_sName, _dName);

                    var pathItemNodes = GetChildrenNodes(itemNode, "HintPath");

                    foreach (var pathItemNode in pathItemNodes)
                    {
                        pathItemNode.InnerText = pathItemNode.InnerText.Replace(_sName, _dName);
                    }
                }
                #endregion
            }

            var PropGroup = GetChildrenNodes(rootNode, "PropertyGroup");

            foreach (var node in PropGroup)
            {
                #region 替换RootNamespace
                var nameSpaceNodes = GetChildrenNodes(node, "RootNamespace");

                foreach (var itemNode in nameSpaceNodes)
                {
                    itemNode.InnerText = itemNode.InnerText.Replace(_sName, _dName);
                }
                #endregion

                #region 替换AssemblyName
                var assemblyNameNodes = GetChildrenNodes(node, "AssemblyName");

                foreach (var itemNode in assemblyNameNodes)
                {
                    itemNode.InnerText = itemNode.InnerText.Replace(_sName, _dName);
                }
                #endregion
            }

            doc.Save(path);
        }


        private static XmlNode[] GetChildrenNodes(XmlNode node, string nodeName)
        {
            if (node == null || node.ChildNodes == null || node.ChildNodes.Count <= 0 || string.IsNullOrEmpty(nodeName))
                return new XmlNode[0];

            IList<XmlNode> childrenNodes = new List<XmlNode>();
            foreach (XmlNode child in node.ChildNodes)
            {
                if (child.Name == nodeName)
                    childrenNodes.Add(child);
            }

            return childrenNodes.ToArray();
        }

        private static XmlAttribute GetNodeAttribute(XmlNode node, string attributeName)
        {
            if (node == null ||
                node.Attributes == null ||
                node.Attributes[attributeName] == null ||
                string.IsNullOrWhiteSpace(attributeName))
                return null;

            return node.Attributes[attributeName];
        }

    }
}
